class Editor {
  constructor(options) {
    this.editorTitle = options.editorTitle;
    this.initialContent = options.initialContent;
    this.subdomain = options.subdomain;
    this.templateName = options.templateName;
    this.resources = [];
    this.dragCounter = 0;
    this.editableTexts = new Map();
    this.seoData = {
      title: "",
      description: "",
      keywords: "",
      author: "",
      robots: "",
    };

    this.init();
  }

  init() {
    this.parseInitialContent();
    // Create and inject editor HTML structure
    const editorHTML = `
            <div class="editor-container">
                <div class="editor-section">
                    <div class="editor-header">
                        <h2>${this.editorTitle}</h2>
                        <div class="editor-actions">
                            <button class="save-btn" id="save-btn">
                                <svg viewBox="0 0 24 24" width="16" height="16">
                                    <path fill="currentColor" d="M17 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V7l-4-4zm2 16H5V5h11.17L19 7.83V19zm-7-7c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z"/>
                                </svg>
                                保存
                            </button>
                            <button class="preview-btn" id="preview-btn">
                                <svg viewBox="0 0 24 24" width="16" height="16">
                                    <path fill="currentColor" d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z"/>
                                </svg>
                                预览
                            </button>
                        </div>
                    </div>
                    <div class="editor-tabs">
                        <button class="editor-tab active" data-tab="text">文字修改</button>
                        <button class="editor-tab" data-tab="seo">SEO设置</button>
                        <button class="editor-tab" data-tab="html">HTML编辑</button>
                    </div>
                    <div class="editor-content">
                        <div id="text-editor" class="tab-content text-editor active">
                            <div id="text-fields"></div>
                        </div>
                        <div id="seo-editor" class="tab-content seo-editor">
                            <div class="seo-field">
                                <label>页面标题 (Title)</label>
                                <input type="text" id="seo-title" placeholder="输入页面标题">
                            </div>
                            <div class="seo-field">
                                <label>页面描述 (Description)</label>
                                <textarea id="seo-description" placeholder="输入页面描述"></textarea>
                            </div>
                            <div class="seo-field">
                                <label>关键词 (Keywords)</label>
                                <input type="text" id="seo-keywords" placeholder="输入关键词，用逗号分隔">
                            </div>
                            <div class="seo-field">
                                <label>作者 (Author)</label>
                                <input type="text" id="seo-author" placeholder="输入作者名称">
                            </div>
                            <div class="seo-field">
                                <label>Robots</label>
                                <input type="text" id="seo-robots" placeholder="例如：index, follow">
                            </div>
                        </div>
                        <div id="html-editor" class="tab-content" style="width: 100%; height: 100%;"></div>
                    </div>
                </div>
                <div class="resource-panel">
                    <div class="resource-header">
                        <h3>资源管理</h3>
                        <div class="resource-actions">
                            <label class="upload-btn">
                                <svg viewBox="0 0 24 24" width="16" height="16">
                                    <path fill="currentColor" d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
                                </svg>
                                上传资源
                                <input type="file" id="resource-upload" multiple accept="image/*,video/*" />
                            </label>
                        </div>
                    </div>
                    <div class="resource-content">
                        <div class="resource-list" id="resource-list"></div>
                    </div>
                </div>
            </div>
        `;

    document.querySelector(".main-content").innerHTML = editorHTML;

    // 配置Ace editor的worker路径
    ace.config.set("basePath", "js/ace");
    ace.config.set("modePath", "js/ace");
    ace.config.set("themePath", "js/ace");
    ace.config.set("workerPath", "js/ace");

    // Initialize Ace editor
    this.htmlEditor = ace.edit("html-editor");
    this.htmlEditor.setTheme("ace/theme/tomorrow_night_blue");
    this.htmlEditor.session.setMode("ace/mode/html");
    this.htmlEditor.setValue(this.initialContent || "", -1);

    // Initialize tabs
    this.initializeTabs();

    // Initialize text fields
    this.renderTextFields();

    // Initialize SEO fields
    this.initializeSeoFields();

    // Enable keyboard handler and commands
    this.htmlEditor.commands.addCommand({
      name: "find",
      bindKey: { win: "Ctrl-F", mac: "Command-F" },
      exec: function (editor) {
        ace.require("ace/ext/searchbox").Search(editor);
      },
    });

    // Enable extensions
    ace.require("ace/ext/language_tools");
    ace.require("ace/ext/searchbox");

    this.htmlEditor.setOptions({
      fontSize: "14px",
      showPrintMargin: false,
      highlightActiveLine: true,
      wrap: true,
      showGutter: true,
      displayIndentGuides: true,
      highlightSelectedWord: true,
      showInvisibles: false,
      useSoftTabs: true,
      tabSize: 2,
      behavioursEnabled: true,
      scrollPastEnd: 0.5,
      enableBasicAutocompletion: true,
      enableSnippets: true,
      enableLiveAutocompletion: true,
    });

    // Set editor colors to match VS Code
    this.htmlEditor.renderer.setScrollMargin(10, 10);
    this.htmlEditor.container.style.lineHeight = "1.5";
    this.htmlEditor.renderer.setShowGutter(true);

    // Initialize other elements
    this.saveBtn = document.getElementById("save-btn");
    this.previewBtn = document.getElementById("preview-btn");
    this.resourceList = document.getElementById("resource-list");
    this.resourceUpload = document.getElementById("resource-upload");

    // Create marker for drag and drop
    this.marker = null;

    // Bind events
    this.saveBtn.addEventListener("click", () => this.saveContent());
    this.previewBtn.addEventListener("click", () => this.openPreview());
    this.resourceUpload.addEventListener("change", (e) =>
      this.uploadResource(e)
    );

    // Load resources
    this.loadResources();
  }

  parseInitialContent() {
    const parser = new DOMParser();
    const doc = parser.parseFromString(this.initialContent, "text/html");

    // Extract SEO data
    this.seoData.title = doc.title || "";
    this.seoData.description =
      doc.querySelector('meta[name="description"]')?.getAttribute("content") ||
      "";
    this.seoData.keywords =
      doc.querySelector('meta[name="keywords"]')?.getAttribute("content") || "";
    this.seoData.author =
      doc.querySelector('meta[name="author"]')?.getAttribute("content") || "";
    this.seoData.robots =
      doc.querySelector('meta[name="robots"]')?.getAttribute("content") || "";

    // Extract editable texts
    doc.querySelectorAll("[data-editable]").forEach((el) => {
      const id = el.getAttribute("data-editable");
      const label = el.getAttribute("data-label") || id;
      this.editableTexts.set(id, {
        label,
        value: el.textContent.trim(),
      });
    });
  }

  initializeTabs() {
    const tabs = document.querySelectorAll(".editor-tab");
    const contents = document.querySelectorAll(".tab-content");

    tabs.forEach((tab) => {
      tab.addEventListener("click", () => {
        const target = tab.getAttribute("data-tab");

        // Update tab states
        tabs.forEach((t) => t.classList.remove("active"));
        tab.classList.add("active");

        // Update content states
        contents.forEach((content) => {
          content.classList.remove("active");
          if (content.id === `${target}-editor`) {
            content.classList.add("active");
          }
        });
      });
    });
  }

  renderTextFields() {
    const container = document.getElementById("text-fields");
    container.innerHTML = "";

    this.editableTexts.forEach((data, id) => {
      const field = document.createElement("div");
      field.className = "text-field";
      field.innerHTML = `
                <label>${data.label}</label>
                <input type="text" id="text-${id}" value="${data.value}" />
            `;

      const input = field.querySelector("input");
      input.addEventListener("input", () => {
        this.updateEditableText(id, input.value);
      });

      container.appendChild(field);
    });
  }

  updateEditableText(id, value) {
    this.editableTexts.set(id, {
      ...this.editableTexts.get(id),
      value,
    });

    const content = this.htmlEditor.getValue();
    const parser = new DOMParser();
    const doc = parser.parseFromString(content, "text/html");

    const element = doc.querySelector(`[data-editable="${id}"]`);
    if (element) {
      element.textContent = value;
      this.htmlEditor.setValue(doc.documentElement.outerHTML, -1);
    }
  }

  initializeSeoFields() {
    // Bind SEO input events
    Object.keys(this.seoData).forEach((key) => {
      const input = document.getElementById(`seo-${key}`);
      if (input) {
        input.value = this.seoData[key];
        input.addEventListener("input", () => {
          this.seoData[key] = input.value;
          this.updateSeoTags();
        });
      }
    });
  }

  updateSeoTags() {
    const content = this.htmlEditor.getValue();
    const parser = new DOMParser();
    const doc = parser.parseFromString(content, "text/html");

    // Update title
    doc.title = this.seoData.title;

    // Update or create meta tags
    const metaTags = {
      description: this.seoData.description,
      keywords: this.seoData.keywords,
      author: this.seoData.author,
      robots: this.seoData.robots,
    };

    Object.entries(metaTags).forEach(([name, content]) => {
      let meta = doc.querySelector(`meta[name="${name}"]`);
      if (!meta && content) {
        meta = doc.createElement("meta");
        meta.setAttribute("name", name);
        doc.head.appendChild(meta);
      }
      if (meta && content) {
        meta.setAttribute("content", content);
      } else if (meta && !content) {
        meta.remove();
      }
    });

    this.htmlEditor.setValue(doc.documentElement.outerHTML, -1);
  }

  async saveContent() {
    // Update content with current editable texts and SEO data
    const content = this.htmlEditor.getValue();
    const endpoint = this.templateName
      ? "save_template.php"
      : "save_landing_page.php";

    let data;
    if (this.templateName) {
      data = {
        template: this.templateName,
        content: content,
      };
    } else if (this.subdomain) {
      data = {
        subdomain: this.subdomain,
        content: content,
      };
    }

    try {
      const response = await fetch(endpoint, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify(data),
      });

      if (response.ok) {
        alert("保存成功！");
      } else {
        throw new Error("保存失败");
      }
    } catch (error) {
      console.error("Save error:", error);
      alert("保存失败：" + error.message);
    }
  }

  openPreview() {
    const content = this.htmlEditor.getValue();
    const previewWindow = window.open("", "_blank");
    if (this.templateName) {
      // For template editing, redirect to template folder
      previewWindow.location.href = `../templates/${this.templateName}/index.html`;
    } else if (this.subdomain) {
      // For landing page editing, redirect to subdomain
      const protocol = window.location.protocol;
      var domainParts = window.location.hostname.split(".");
      if (domainParts.length > 2) {
        domainParts.shift();
      }
      const domain = domainParts.join(".");
      previewWindow.location.href = `${protocol}//${this.subdomain}.${domain}`;
    } else {
      // For new content, display in new window
      previewWindow.document.write(content);
      previewWindow.document.close();
    }
  }

  getResourcePreview(resource) {
    const ext = resource.filename.split(".").pop().toLowerCase();
    const isVideo = ["mp4", "webm", "ogg"].includes(ext);

    // 构建尺寸标签
    const dimensionsTag = resource.dimensionsText
      ? `
            <div class="resource-dimensions">
                <svg viewBox="0 0 24 24" width="12" height="12">
                    <path fill="currentColor" d="M19 12h-2v3h-3v2h5v-5zM7 9h3V7H5v5h2V9zm14-6H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H3V5h18v14z"/>
                </svg>
                ${resource.dimensionsText}
            </div>
        `
      : "";

    if (isVideo) {
      const videoId = `video-${Math.random().toString(36).substr(2, 9)}`;
      setTimeout(() => {
        const video = document.getElementById(videoId);
        if (video && !resource.dimensionsText) {
          video.addEventListener("loadedmetadata", () => {
            const width = video.videoWidth;
            const height = video.videoHeight;
            if (width && height) {
              const dimensionsDiv = video.parentElement.querySelector(
                ".resource-dimensions"
              );
              if (!dimensionsDiv) {
                const newDimensionsDiv = document.createElement("div");
                newDimensionsDiv.className = "resource-dimensions";
                newDimensionsDiv.innerHTML = `
                                    <svg viewBox="0 0 24 24" width="12" height="12">
                                        <path fill="currentColor" d="M19 12h-2v3h-3v2h5v-5zM7 9h3V7H5v5h2V9zm14-6H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H3V5h18v14z"/>
                                    </svg>
                                    ${width}x${height}
                                `;
                video.parentElement.appendChild(newDimensionsDiv);
              }
            }
          });
        }
      }, 0);

      return `
                <div class="resource-preview">
                    <video id="${videoId}" src="${resource.url}" muted loop>
                        <source src="${resource.url}" type="video/${ext}">
                    </video>
                    ${dimensionsTag}
                </div>
            `;
    }
    return `
            <div class="resource-preview">
                <img src="${resource.url}" alt="${
      resource.description || ""
    }" />
                ${dimensionsTag}
            </div>
        `;
  }

  async loadResources() {
    try {
      // 构建请求URL，根据是否是落地页编辑决定是否传递template参数
      const params = new URLSearchParams();
      if (this.subdomain) {
        params.append("subdomain", this.subdomain);
      } else if (this.templateName) {
        params.append("template", this.templateName);
      }

      const response = await fetch(`get_resources.php?${params.toString()}`);
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }
      const data = await response.json();
      this.resources = Array.isArray(data) ? data : [];
      this.renderResources();
    } catch (error) {
      console.error("Failed to load resources:", error);
      this.resources = [];
      this.renderResources();
    }
  }

  renderResources() {
    this.resourceList.innerHTML = this.resources
      .map(
        (resource) => `
            <div class="resource-item" draggable="true" data-url="${
              resource.url
            }" data-path="resources/${resource.filename}">
                ${this.getResourcePreview(resource)}
                <div class="resource-info">
                    <span class="resource-name">${resource.filename}</span>
                    <div class="resource-actions">
                        <button class="copy-btn" onclick="event.stopPropagation(); this.closest('.resource-item').dispatchEvent(new Event('copy'))">
                            <svg viewBox="0 0 24 24" width="14" height="14">
                                <path fill="currentColor" d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7l-4-4zm3 16H8V7h6v5h5v9z"/>
                            </svg>
                        </button>
                        <button class="replace-btn" onclick="event.stopPropagation(); this.querySelector('input').click()">
                            <svg viewBox="0 0 24 24" width="14" height="14">
                                <path fill="currentColor" d="M19 8l-4 4h3c0 3.31-2.69 6-6 6-1.01 0-1.97-.25-2.8-.7l-1.46 1.46C8.97 19.54 10.43 20 12 20c4.42 0 8-3.58 8-8h3l-4-4zM6 12c0-3.31 2.69-6 6-6 1.01 0 1.97.25 2.8.7l1.46-1.46C15.03 4.46 13.57 4 12 4c-4.42 0-8 3.58-8 8H1l4 4 4-4H6z"/>
                            </svg>
                            <input type="file" style="display:none" onchange="this.closest('.resource-item').dispatchEvent(new CustomEvent('replace', {detail: this.files[0]}))" />
                        </button>
                        <button class="delete-btn" onclick="event.stopPropagation(); this.closest('.resource-item').dispatchEvent(new Event('delete'))">
                            <svg viewBox="0 0 24 24" width="14" height="14">
                                <path fill="currentColor" d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"/>
                            </svg>
                        </button>
                    </div>
                </div>
            </div>
        `
      )
      .join("");

    // Add event listeners to resource items
    this.resourceList.querySelectorAll(".resource-item").forEach((item) => {
      // Drag event
      item.addEventListener("dragstart", (e) => {
        // 阻止事件冒泡
        e.stopPropagation();
        // 清除之前可能存在的数据
        e.dataTransfer.clearData();
        // 设置新的路径数据
        const path = item.dataset.path;
        e.dataTransfer.setData("text/plain", path);
        // 设置允许的效果
        e.dataTransfer.effectAllowed = "copy";
      });

      // Copy event
      item.addEventListener("copy", () => {
        const path = item.dataset.path;

        // 创建一个临时textarea元素
        const textarea = document.createElement("textarea");
        textarea.value = path;
        textarea.style.position = "fixed";
        textarea.style.left = "-9999px";
        document.body.appendChild(textarea);

        try {
          // 选择并复制文本
          textarea.select();
          document.execCommand("copy");

          // 显示复制成功的视觉反馈
          const btn = item.querySelector(".copy-btn");
          btn.style.color = "#4CAF50";
          setTimeout(() => (btn.style.color = ""), 1000);
        } catch (err) {
          console.error("复制失败:", err);
        } finally {
          // 移除临时元素
          document.body.removeChild(textarea);
        }
      });

      // Replace event
      item.addEventListener("replace", async (e) => {
        const file = e.detail;
        const formData = new FormData();
        formData.append("file", file);
        formData.append(
          "old_file",
          item.querySelector(".resource-name").textContent
        );
        var prefix = "";
        if (this.subdomain) {
          formData.append("subdomain", this.subdomain);
          prefix = "/landing_pages/" + this.subdomain + "/";
        } else if (this.templateName) {
          formData.append("template", this.templateName);
          prefix = "/templates/" + this.templateName + "/";
        }

        try {
          const response = await fetch("replace_resource.php", {
            method: "POST",
            body: formData,
          });

          if (response.ok) {
            const result = await response.json();
            if (result.success) {
              // Get the old and new paths
              const oldPath = item.dataset.path;
              const newPath = "resources/" + result.resource.filename;

              // Replace all occurrences of the old path in the editor
              let content = this.htmlEditor
                .getValue()
                .replaceAll(oldPath, newPath);

              // 如果是视频文件且包含缩略图，更新poster属性
              if (result.resource.type === "video") {
                const parser = new DOMParser();
                const doc = parser.parseFromString(content, "text/html");

                // 更新video标签的poster属性
                doc.querySelectorAll("video").forEach((video) => {
                  // 获取当前 video 元素下的所有 source 元素
                  const sources = video.querySelectorAll("source");

                  // 遍历每个 source 元素
                  sources.forEach((source) => {
                    if (source.src.includes(newPath)) {
                      // 如果 source 的 src 包含 newPath，则设置 video 的海报
                      video.poster = result.resource.thumbnail || "";
                    }
                  });
                });

                content = doc.documentElement.outerHTML;
              }
              // 自动保存修改
              this.htmlEditor.setValue(content, -1);
              // Reload resources
              await this.loadResources();
              await this.saveContent();
            } else {
              throw new Error(result.error || "替换失败");
            }
          } else {
            throw new Error("替换失败");
          }
        } catch (error) {
          console.error("Replace error:", error);
          alert("替换失败：" + error.message);
        }
      });

      // Delete event
      item.addEventListener("delete", async () => {
        if (!confirm("确定要删除这个资源吗？")) return;

        try {
          const response = await fetch("delete_resource.php", {
            method: "POST",
            headers: {
              "Content-Type": "application/json",
            },
            body: JSON.stringify({
              filename: item.querySelector(".resource-name").textContent,
              subdomain: this.subdomain || "",
              template: this.templateName || "",
            }),
          });

          if (response.ok) {
            await this.loadResources();
          } else {
            console.error("Delete failed");
          }
        } catch (error) {
          console.error("Delete error:", error);
        }
      });
    });
  }

  async uploadResource(event) {
    const files = event.target.files;
    if (!files.length) return;

    // 创建进度条容器并添加到页面右下角（修复z-index问题）
    const progressContainer = document.createElement("div");
    progressContainer.className = "upload-progress-container";
    progressContainer.style.zIndex = "9999";
    document.body.appendChild(progressContainer);

    const uploadPromises = [];
    const progressBars = new Map();

    // 为每个文件创建进度条
    for (let file of files) {
      const progressItem = document.createElement("div");
      progressItem.className = "upload-progress-item";

      const fileName = document.createElement("span");
      fileName.className = "upload-file-name";
      fileName.textContent = file.name;

      const progressBar = document.createElement("div");
      progressBar.className = "upload-progress-bar";
      progressBar.setAttribute("data-progress", "0%");
      progressBar.style.position = "relative";

      const progressFill = document.createElement("div");
      progressFill.className = "upload-progress-fill";
      progressBar.appendChild(progressFill);

      progressItem.appendChild(fileName);
      progressItem.appendChild(progressBar);
      progressContainer.appendChild(progressItem);

      progressBars.set(file, progressFill);
    }

    // 上传每个文件
    for (let file of files) {
      const formData = new FormData();
      formData.append("files[]", file);
      if (this.subdomain) {
        formData.append("subdomain", this.subdomain);
      } else if (this.templateName) {
        formData.append("template", this.templateName);
      }

      const uploadPromise = new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest();
        const progressPercent = document.createElement("div");
        progressPercent.className = "upload-progress-percent";

        xhr.upload.addEventListener("progress", (e) => {
          if (e.lengthComputable) {
            const percent = Math.round((e.loaded / e.total) * 100);
            progressPercent.textContent = `${percent}%`;
            progressFill.style.width = `${percent}%`;
          }
        });

        xhr.addEventListener("load", () => {
          if (xhr.status === 200) {
            resolve(xhr.response);
          } else {
            reject(new Error(`Upload failed: ${xhr.statusText}`));
          }
        });

        xhr.addEventListener("error", () => {
          reject(new Error("Upload failed"));
        });

        xhr.open("POST", "upload_resource.php");
        xhr.send(formData);
      });

      uploadPromises.push(uploadPromise);
    }

    try {
      await Promise.all(uploadPromises);
      await this.loadResources();
      event.target.value = "";
    } catch (error) {
      console.error("Upload error:", error);
    } finally {
      // 延迟移除进度条容器
      setTimeout(() => {
        progressContainer.remove();
      }, 1000);
    }
  }
}
